#include "hcsr04.h"

#include "stm32f1xx_hal.h"
#include "delay.h"

#define HCSR04_ECHO_Pin       GPIO_PIN_2
#define HCSR04_ECHO_GPIO_Port GPIOA
#define HCSR04_ECHO_EXTI_IRQn EXTI2_IRQn
#define HCSR04_ECHO_GPIO_CLK_ENABLE() \
    do {                              \
        __HAL_RCC_GPIOA_CLK_ENABLE(); \
    } while (0)

#define HCSR04_TRIG_Pin       GPIO_PIN_3
#define HCSR04_TRIG_GPIO_Port GPIOA
#define HCSR04_TRIG_GPIO_CLK_ENABLE() \
    do {                              \
        __HAL_RCC_GPIOA_CLK_ENABLE(); \
    } while (0)


#define HCSR04_TRIG(x)                                                                 \
    do {                                                                               \
        x ? HAL_GPIO_WritePin(HCSR04_TRIG_GPIO_Port, HCSR04_TRIG_Pin, GPIO_PIN_SET)    \
          : HAL_GPIO_WritePin(HCSR04_TRIG_GPIO_Port, HCSR04_TRIG_Pin, GPIO_PIN_RESET); \
    } while (0)

#define HCSR04_READ_ECHO() HAL_GPIO_ReadPin(HCSR04_ECHO_GPIO_Port, HCSR04_ECHO_Pin)

extern TIM_HandleTypeDef htim3;
int                      tim_count = 0;
float                    distance_cm  = 0;

void HCSR04_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    HCSR04_ECHO_GPIO_CLK_ENABLE();
    HCSR04_TRIG_GPIO_CLK_ENABLE();

    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(HCSR04_TRIG_GPIO_Port, HCSR04_TRIG_Pin, GPIO_PIN_RESET);


    /*Configure GPIO pin : HCSR04_ECHO_Pin */
    GPIO_InitStruct.Pin  = HCSR04_ECHO_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(HCSR04_ECHO_GPIO_Port, &GPIO_InitStruct);

    /*Configure GPIO pin : HCSR04_TRIG_Pin */
    GPIO_InitStruct.Pin   = HCSR04_TRIG_Pin;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(HCSR04_TRIG_GPIO_Port, &GPIO_InitStruct);

    /* EXTI interrupt init*/
    HAL_NVIC_SetPriority(EXTI2_IRQn, 7, 0);
    HAL_NVIC_EnableIRQ(EXTI2_IRQn);
}

void HCSR04_TrigSig(void)
{
    HCSR04_TRIG(1);
    delay_us(10);
    HCSR04_TRIG(0);
}

void HCSR04_ReadDist(void)
{
    static uint32_t time_us = 0;

    if (HCSR04_READ_ECHO() == GPIO_PIN_SET) {
        HAL_TIM_Base_Start(&htim3);
        __HAL_TIM_SetCounter(&htim3, 0);
    }
    else if (HCSR04_READ_ECHO() == GPIO_PIN_RESET) {
        HAL_TIM_Base_Stop(&htim3);
        time_us     = __HAL_TIM_GetCounter(&htim3);
        distance_cm = (float)time_us * 340 / 2 * 0.000001 * 100;
    }
}
